package doc.ic.walkmore;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.Toast;
import android.widget.ToggleButton;
import doc.ic.walkmore.DAO.StepsDataSource;
import doc.ic.walkmore.DAO.StepsDataSourceWrittable;
import doc.ic.walkmore.GUI.GUIManager;
import doc.ic.walkmore.services.DetectMvtSensorService;

public class MainActivity extends Activity {

	// DetectMvt Service
	private boolean mDetectMvtServiceBound;
	private DetectMvtSensorService mDetectMvtService;
	private Intent mDetectMvtServiceIntent;
	
	// Notification service
	private NotificationManager mNM;
	
	// Views
//	private ToggleButton mButtonToggleSensing;
	private LinearLayout mainView;
	
	// Dates
	SimpleDateFormat dayFormating = new SimpleDateFormat("yyyy-MM-dd");
	private String today;
		
	// Database storing stats
	private StepsDataSourceWrittable datasource;

	// GUI
	private GUIManager mGui;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);		
	   	
		// ---------------------
		// Start detect movement service
		// ---------------------
	   	// Intent for the activity sensoring service
	   	mDetectMvtServiceIntent = new Intent(this, DetectMvtSensorService.class);
	   	// Explicitly start the service, to leave it running (so explicitly have to stop it)
	   	startService(mDetectMvtServiceIntent);
	   	// doBind service
	   	bindService(mDetectMvtServiceIntent, mDetectMvtConnection, Context.BIND_AUTO_CREATE);
	   	// ---------------------
	   	
    	// Notification service
        mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
        
	   	// Prepare GUI
		setContentView(R.layout.stepcount);
		mainView = (LinearLayout) findViewById(R.id.mainLayout);
//		mButtonToggleSensing = (ToggleButton) mainView.findViewById(R.id.toggleButton1);
		mGui = new GUIManager(this,mainView);
		
		
        // DataSource
        datasource = new StepsDataSourceWrittable(this, mGui);
        datasource.open();
    	
        // Creation successful: send notification to user
        showNotification("WalkMore", "Running and ready to detect activity..");
	}
	
	@Override
	protected void onResume() {
		today = dayFormating.format(new Date());
			
		super.onResume();
	}
		
	
	/**
	 * onClickListener button show daily graph
	 * @param the button clicked
	 */
	public void dailyGraph(View v)  {
		Intent graphView = new Intent(this, GraphActivity.class);
		graphView.putExtra("date", mGui.getDateToDisplay());
		startActivityForResult(graphView, 0);
	}
	/**
	 * onClickListener button change date
	 * @param the button clicked
	 */
	public void nextDay(View v)  {
		String oldDay = mGui.getDateToDisplay();
		//Don't go in the future
		if (!oldDay.equals(today)) {
			Calendar c = Calendar.getInstance();
			try {
				c.setTime(dayFormating.parse(oldDay));
			} catch (ParseException e) {
				e.printStackTrace();
				return;
			}
			c.add(Calendar.DATE, 1);  // number of days to add
			mGui.setDayToDisplay(dayFormating.format(c.getTime()));  // dt is now the new date
		} else {
			Toast toast = Toast.makeText(this, R.string.noData, Toast.LENGTH_SHORT);
			toast.show();
		}
		
		//  don't change date if no data for next day
		if (!datasource.hasData(mGui.getDateToDisplay())) {
			mGui.setDayToDisplay(oldDay);  // come back to old date
			Toast toast = Toast.makeText(this, R.string.noData, Toast.LENGTH_SHORT);
			toast.show();
		}
		
		// Update GUI
		datasource.updateGUI(mGui.getDateToDisplay());
	}
	
	/**
	 * onClickListener gui button change date
	 * @param the button clicked
	 */
	public void prevDay(View v)  {
		String oldDay = mGui.getDateToDisplay();
		Calendar c = Calendar.getInstance();
		try {
			c.setTime(dayFormating.parse(oldDay));
		} catch (ParseException e) {
			e.printStackTrace();
			return;
		}
		c.add(Calendar.DATE, -1);  // number of days to add (here substract)
		mGui.setDayToDisplay(dayFormating.format(c.getTime()));  // dt is now the new date
		
		//  don't change date if no data from previous day
		if (!datasource.hasData(mGui.getDateToDisplay())) {
			mGui.setDayToDisplay(oldDay);  // come back to old date
			// Warn user no data
			Toast toast = Toast.makeText(this, R.string.noData, Toast.LENGTH_LONG);
			toast.show();
		}
		
		// Updatae GUI
		datasource.updateGUI(mGui.getDateToDisplay());
	}
	
	/** Defines callbacks for service binding, passed to bindService() */
    private ServiceConnection mDetectMvtConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className,
                IBinder service) {
            // We've bound to LocalService, cast the IBinder and get LocalService instance
            DetectMvtSensorService.LocalBinder binder = (DetectMvtSensorService.LocalBinder) service;
            mDetectMvtService = binder.getService();
            mDetectMvtServiceBound = true;
            mDetectMvtService.setDataSource(datasource);
            mDetectMvtService.launchDetectMvtScheduler();
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
        	mDetectMvtServiceBound = false;
        }
    };
    
	// Start/stop sensing button listener
    public void toggleSensingButton(View v) {
    	ToggleButton button = (ToggleButton) v;
        if (button.isChecked()) {
            // Start sensing
        	mDetectMvtService.startActivitySensing();
        } else {
            // stop sensing
        	mDetectMvtService.stopActivitySensing();
        }
    }	
    
    // reset button listener
	public void reset(View v) {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
    	builder.setMessage(getString(R.string.confirm_reset))
    	       .setCancelable(false)
    	       .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
    	           public void onClick(DialogInterface dialog, int id) {
    					datasource.delete(today);
    	           }
    	       })
    	       .setNegativeButton("No", new DialogInterface.OnClickListener() {
    	           public void onClick(DialogInterface dialog, int id) {
    	                dialog.cancel();
    	           }
    	       });
    	AlertDialog alert = builder.create();
    	alert.show();
	}


    @Override
    public void onBackPressed() {
    	// Don't quit the app, just pause it
    	moveTaskToBack(true);
    }
    
    public void exitApp(View v) {
    	AlertDialog.Builder builder = new AlertDialog.Builder(this);
    	builder.setMessage(getString(R.string.confirm_exit))
    	       .setCancelable(false)
    	       .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
    	           public void onClick(DialogInterface dialog, int id) {
    	                MainActivity.this.finish();
    	           }
    	       })
    	       .setNegativeButton("No", new DialogInterface.OnClickListener() {
    	           public void onClick(DialogInterface dialog, int id) {
    	                dialog.cancel();
    	           }
    	       });
    	AlertDialog alert = builder.create();
    	alert.show();
    }
    
    @Override
    protected void onDestroy() {
    	// Removing notification
    	mNM.cancelAll();
    	
    	// Close Database
    	datasource.close();
    	
    	// Stop DetectMvt service
    	if (mDetectMvtServiceBound)
    		unbindService(mDetectMvtConnection);
    	stopService(mDetectMvtServiceIntent);

    	super.onDestroy();
    }
	
    /**
     * Show a notification while this service is running.
     */
    private void showNotification(CharSequence title, CharSequence text) {
        // Set the icon, scrolling text and timestamp
        Notification notification = new Notification(R.drawable.ic_launcher_notif, text,
                System.currentTimeMillis());

        // The PendingIntent to launch our activity if the user selects this notification
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                new Intent(getApplicationContext(), MainActivity.class), 0);

        // Set the info for the views that show in the notification panel.
        notification.setLatestEventInfo(this, title,
        		text, contentIntent);

        // Send the notification.
        // We use a layout id because it is a unique number.  We use it later to cancel.
        mNM.notify(R.string.local_service_started, notification);
    }
}
